package com.sx.medicinecard.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**



 签名计算工具类

 @author xueweiping

 */

@Slf4j

public class SignUtil {

    private SignUtil(){}


    private static final String SIGN = "sign";

    private static final DateTimeFormatter DATE_TIME_FORMATTER =

            DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneOffset.UTC);

    /**

     * 生成sign

     *

     * @param params

     * @param secretKey 密钥

     * @return java.lang.String

     * @author xueweiping

     * @date 2020/9/3 14:32

     */

    public static String generateSign(Map<String, Object> params, String secretKey) {

        String encodeString = getEncodeString(params, secretKey);

        return generateSign(encodeString);

    }


    private static String getEncodeString(Map<String, Object> params, String secretKey) {

        Iterator<String> iterator = params.keySet().iterator();

        Set<String> sortedParams = new TreeSet<>();

        while (iterator.hasNext()) {

            sortedParams.add(iterator.next());

        }

        StringBuilder stringBuilder = new StringBuilder(secretKey);

        for (String key : sortedParams) {

            if (SIGN.equals(key)) {

                continue;

            }

            String value = params.get(key).toString();

            if (StringUtils.isNotEmpty(value)) {

                stringBuilder.append(key).append(value);

            }

        }

        return stringBuilder.toString();

    }


    private static String generateSign(String content) {

        return DigestUtils.md5DigestAsHex(content.getBytes());

    }


    // 签名
    public static String sign(String appKey, String appSecret, String content) {
        StringBuilder keyBuilder = new StringBuilder();
        keyBuilder.append(appKey).append(content);
        return Md5Util.MD5(encrypt(keyBuilder.toString(), appSecret, "HmacSHA256"));
    }

    // HmacSHA256加密算法获取加密串
    public static String encrypt(String key, String appSecret, String cryptoType) {
        try {
            SecretKeySpec signingKey = getSecretKey(appSecret, cryptoType);
            Mac mac = Mac.getInstance(cryptoType);
            mac.init(signingKey);
            byte[] rawHmac = mac.doFinal(key.getBytes());
            String hexBytes = byte2hex(rawHmac);
            return hexBytes;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static SecretKeySpec getSecretKey(String appSecret, String cryptoType) {
        try {
            byte[] keyBytes = appSecret.getBytes();
            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, cryptoType);
            return secretKey;
        } catch (Exception var4) {
            return null;
        }
    }

    private static String byte2hex(final byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0xFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs;
    }


    public static void main(String[] args) {

//        String sign = generateSign(new HashMap<>(),"12121212");
//
//        System.out.println(sign);

        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();

        // 获取一年后的时间
        LocalDateTime oneYearLater = now.plusYears(1);

        // 将一年后的时间转换为时间戳，并转换为秒为单位的10位时间戳
        long oneYearLaterTimeStamp = oneYearLater.toEpochSecond(ZoneOffset.UTC);


        JSONObject paramJson = new JSONObject();
        paramJson.put("userPhone","19159612594");
        paramJson.put("channelCode","8793");
        paramJson.put("startTime",System.currentTimeMillis() / 1000);
        paramJson.put("endTime",oneYearLaterTimeStamp);
        Map<String,Object> reqMap = new HashMap<>();
        reqMap.put("appId", "ykqyuanke87J1d7PK");
        reqMap.put("timestamp", System.currentTimeMillis() / 1000);
        reqMap.put("paramJson", JSON.toJSONString(paramJson));
        String signature = SignUtil.generateSign(reqMap, "0a3b2053fd627a5948bd8597f4a86d3e");
        log.info("sign: {}", signature);
        reqMap.put("sign", signature);

        log.info("reqParams:{}", JSON.toJSONString(reqMap));

        JSONObject sendJson = new JSONObject();
        sendJson.put("appId", "ykqyuanke87J1d7PK");
        sendJson.put("timestamp", System.currentTimeMillis() / 1000);
        sendJson.put("paramJson", JSON.toJSONString(paramJson));
        sendJson.put("sign", signature);

//        String result = HttpUtil.post("https://openapi-ykq.test.ybm100.com/openapi/v1/channel/activationRights", reqMap, 3000);

        String string = HttpUtils.doPost(sendJson, "https://openapi-ykq.test.ybm100.com/openapi/v1/channel/activationRights");
        String string1 = JSONObject.parseObject(string).getJSONObject("data").getString("receiveId");
        System.out.println(string1);

        log.info("req result: {}", string);

    }


}
